﻿using System;

namespace IniTechCaash.Domain.Entities
{
    /// <summary>
    /// This is the classification of an <see cref="Account"/>. 
    /// </summary>
    public enum AccountType
    {
        CurrentAsset,
        LongTermAsset,
        InventoryAsset,
        EquipmentAsset,
        IntangibleAsset,
        SalesReturnsAndAllowances,

        Equity,
        CommonStockEquity,
        RetainedEarningsEquity,

        Expense,
        CostOfGoodsSoldExpense,
        DividendExpense,

        CurrentLiability,
        LongTermLiability,

        OtherIncomeRevenue,
        SalesRevenue,
        ServiceRevenue,
    }

    public enum GeneralAccountType
    {
        Asset,
        Equity,
        Expense,
        Liability,
        Revenue,
    }

    public static class AccountTypeExtensions
    {
        public static AccountType[] GetAccountTypes(this GeneralAccountType type)
        {
            if (type == GeneralAccountType.Asset)
                return new AccountType[] {
                AccountType.CurrentAsset,
                AccountType.LongTermAsset,
                AccountType.InventoryAsset,
                AccountType.EquipmentAsset,
                AccountType.IntangibleAsset,
                AccountType.SalesReturnsAndAllowances,
                };
            if (type == GeneralAccountType.Equity)
                return new AccountType[] {
                    AccountType.Equity,
                    AccountType.CommonStockEquity,
                    AccountType.RetainedEarningsEquity,
                };
            if (type == GeneralAccountType.Expense)
                return new AccountType[] {
                    AccountType.Expense,
                    AccountType.CostOfGoodsSoldExpense,
                    AccountType.DividendExpense,
                };
            if (type == GeneralAccountType.Liability)
                return new AccountType[] {
                    AccountType.CurrentLiability,
                    AccountType.LongTermLiability,
                };
            if (type == GeneralAccountType.Revenue)
                return new AccountType[] {
                    AccountType.OtherIncomeRevenue,
                    AccountType.SalesRevenue,
                    AccountType.ServiceRevenue,
                };
            throw new Exception();
        }

        public static GeneralAccountType GetGeneralAccountType(this AccountType type)
        {
            switch (type)
            {
                case AccountType.CurrentAsset:
                case AccountType.LongTermAsset:
                case AccountType.InventoryAsset:
                case AccountType.EquipmentAsset:
                case AccountType.IntangibleAsset:
                case AccountType.SalesReturnsAndAllowances:
                    return GeneralAccountType.Asset;
                case AccountType.Equity:
                case AccountType.CommonStockEquity:
                case AccountType.RetainedEarningsEquity:
                    return GeneralAccountType.Equity;
                case AccountType.Expense:
                case AccountType.CostOfGoodsSoldExpense:
                case AccountType.DividendExpense:
                    return GeneralAccountType.Expense;
                case AccountType.CurrentLiability:
                case AccountType.LongTermLiability:
                    return GeneralAccountType.Liability;
                case AccountType.OtherIncomeRevenue:
                case AccountType.SalesRevenue:
                case AccountType.ServiceRevenue:
                    return GeneralAccountType.Revenue;
                default:
                    return 0;
            }
        }

        public static int GetNumberPrefix(this AccountType type)
        {
            switch (type)
            {
                case AccountType.CurrentAsset:
                case AccountType.LongTermAsset:
                case AccountType.InventoryAsset:
                case AccountType.EquipmentAsset:
                case AccountType.IntangibleAsset:
                case AccountType.SalesReturnsAndAllowances:
                    return 1;
                case AccountType.Equity:
                case AccountType.CommonStockEquity:
                case AccountType.RetainedEarningsEquity:
                    return 2;
                case AccountType.Expense:
                case AccountType.CostOfGoodsSoldExpense:
                case AccountType.DividendExpense:
                    return 3;
                case AccountType.CurrentLiability:
                case AccountType.LongTermLiability:
                    return 4;
                case AccountType.OtherIncomeRevenue:
                case AccountType.SalesRevenue:
                case AccountType.ServiceRevenue:
                    return 5;
                default:
                    return 0;
            }
        }

        public static NormalSide GetNormalSide(this AccountType type)
        {
            switch (type)
            {
                case AccountType.CurrentAsset:
                case AccountType.LongTermAsset:
                case AccountType.InventoryAsset:
                case AccountType.EquipmentAsset:
                case AccountType.IntangibleAsset:
                case AccountType.SalesReturnsAndAllowances:
                    return NormalSide.Debit;
                case AccountType.Equity:
                case AccountType.CommonStockEquity:
                case AccountType.RetainedEarningsEquity:
                    return NormalSide.Credit;
                case AccountType.Expense:
                case AccountType.CostOfGoodsSoldExpense:
                case AccountType.DividendExpense:
                    return NormalSide.Debit;
                case AccountType.CurrentLiability:
                case AccountType.LongTermLiability:
                    return NormalSide.Credit;
                case AccountType.OtherIncomeRevenue:
                case AccountType.SalesRevenue:
                case AccountType.ServiceRevenue:
                    return NormalSide.Credit;
                default:
                    return NormalSide.Debit;
            }
        }
    }
}
